/**************************************************************************/
/*                                                                        */
/* Copyright (c) 2017 KYE Company                                       */
/* 跨越速运集团有限公司版权所有                                           */
/*                                                                        */
/* PROPRIETARY RIGHTS of KYE Company are involved in the                */
/* subject matter of this material. All manufacturing, reproduction, use, */
/* and sales rights pertaining to this subject matter are governed by the */
/* license agreement. The recipient of this software implicitly accepts   */
/* the terms of the license.                                              */
/* 本软件文档资料是跨越速运集团有限公司的资产，任何人士阅读和                   */
/* 使用本资料必须获得相应的书面授权，承担保密责任和接受相应的法律约束。                 */
/*                                                                        */
/**************************************************************************/

/**
  * <pre>
  * 作   者：liwei
  * 创建日期：2018-1-4
  * </pre>
  */

package com.kyexpress.common.hrinterview.provider.controller;

import com.kyexpress.common.hrinterview.api.bo.DepartmentCount;
import com.kyexpress.common.hrinterview.api.bo.StatisticsBo;
import com.kyexpress.common.hrinterview.api.model.Employee;
import com.kyexpress.common.hrinterview.api.model.EmployeeStudyExp;
import com.kyexpress.common.hrinterview.api.model.EmployeeUpload;
import com.kyexpress.common.hrinterview.api.model.EmployeeWorkExp;
import com.kyexpress.common.hrinterview.api.service.EmployeeRemoteService;
import com.kyexpress.common.hrinterview.provider.service.EmployeeService;
import com.kyexpress.common.hrinterview.provider.service.EmployeeStudyExpService;
import com.kyexpress.common.hrinterview.provider.service.EmployeeUploadService;
import com.kyexpress.common.hrinterview.provider.service.EmployeeWorkExpService;
import com.kyexpress.common.hrinterview.provider.utils.*;
import com.kyexpress.common.idcenter.IdGenClient;
import com.kyexpress.framework.annotation.PropertyFiltration;
import com.kyexpress.framework.exception.ApplicationException;
import com.kyexpress.framework.model.ResponseData;
import com.kyexpress.framework.utils.DateUtils;
import com.kyexpress.framework.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.util.List;
import java.util.regex.Pattern;

/**
 * <pre>
 * 表现层控制类
 * </pre>
 */
@RestController
public class EmployeeController implements EmployeeRemoteService {
    private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);
    
    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private EmployeeStudyExpService employeeStudyExpService;

    @Autowired
    private EmployeeWorkExpService employeeWorkExpService;

    @Autowired
    private EmployeeUploadService employeeUploadService;

    @Override
    public ResponseData<String> save(@RequestBody Employee bo) {
        // 登陆校验
        if(!InterviewUtils.isLogin()){
            throw new ApplicationException(ErrorEnum.UserNotLogin.getCode(), ErrorEnum.UserNotLogin.getMsg());
        }
        // 数据校验
        checkNameLegal(bo.getName());
        checkTelLegal(bo.getTel());
        checkInterviewTimeLegal(bo.getInterviewTime());
        checkOfficeLocationLegal(bo.getOfficeLocation());
        checkEmailLegal(bo.getEmail());
        checkDepartmentLegal(bo.getDepartment());
        checkPositionLegal(bo.getPosition());
        // convert bo to model
        Employee data = new Employee();
        data.setId(IdGenClient.getId());
        data.setEnabledFlag(1L);
        data.setName(bo.getName().trim());
        data.setTel(bo.getTel().trim());
        data.setInterviewTime(bo.getInterviewTime());
        data.setOfficeLocation(bo.getOfficeLocation().trim());
        data.setEmail(bo.getEmail().trim());
        data.setDepartment(bo.getDepartment().trim());
        data.setPosition(bo.getPosition().trim());
        // save
        ResponseData<String> result = new ResponseData<>();
        try {
            employeeService.insertSelective(data);
            result.setData(String.valueOf(data.getId())).ok();
        } catch (Exception e) {
            logger.error("EmployeeController.save", e);
            result.responseCode(ErrorEnum.SystemError.getCode(), ErrorEnum.SystemError.getMsg());
        }
        return result;
    }

    @Override
    public ResponseData<String> update(@RequestBody Employee bo) {
        Employee data = new Employee();
        checkIdLegal(bo.getId());
        data.setId(bo.getId());
        // 登陆状态：登陆（管理人员）可修改关键信息（姓名etc）；未登录可修改非关键信息
        if(InterviewUtils.isLogin()) {
            data.setInterviewTime(null == bo.getInterviewTime() ? null : bo.getInterviewTime());
            data.setOfficeLocation(formatString(bo.getOfficeLocation()));
            data.setName(formatString(bo.getName()));
            data.setDepartment(formatString(bo.getDepartment()));
            data.setProbationSalary(formatString(bo.getProbationSalary()));
            data.setBecomeSalary(formatString(bo.getBecomeSalary()));
            data.setProbationTime(bo.getProbationTime());
            data.setGangTime(null == bo.getGangTime() ? null : bo.getGangTime());
            data.setOpinion(formatString(bo.getOpinion()));
            data.setBackgroundCheck(bo.getBackgroundCheck());
            data.setStatus(bo.getStatus());
            data.setOffer(bo.getOffer());
        }
        // convert bo to model
        data.setEmail(formatString(bo.getEmail()));
        data.setPosition(formatString(bo.getPosition()));
        data.setEntryTime(null == bo.getEntryTime() ? null : bo.getEntryTime());
        data.setSex(bo.getSex());
        data.setTel(formatString(bo.getTel()));
        data.setBirthday(null == bo.getBirthday() ? null : bo.getBirthday());
        data.setAge(bo.getAge());
        data.setNation(formatString(bo.getNation()));
        data.setNativePlace(formatString(bo.getNativePlace()));
        data.setHeight(bo.getHeight());
        data.setWeight(bo.getWeight());
        data.setBloodType(formatString(bo.getBloodType()));
        data.setIllHistory(formatString(bo.getIllHistory()));
        data.setWx(formatString(bo.getWx()));
        data.setQq(formatString(bo.getQq()));
        data.setSchool(formatString(bo.getSchool()));
        data.setEducation(bo.getEducation());
        data.setProfession(formatString(bo.getProfession()));
        data.setMarry(bo.getMarry());
        data.setLanguage(formatString(bo.getLanguage()));
        data.setSkill(formatString(bo.getSkill()));
        data.setExpectationSalary(formatString(bo.getExpectationSalary()));
        data.setIdentityCart(formatString(bo.getIdentityCart()));
        data.setBankCard(formatString(bo.getBankCard()));
        data.setOfficeTel(formatString(bo.getOfficeTel()));
        data.setAddress(formatString(bo.getAddress()));
        data.setContactName(formatString(bo.getContactName()));
        data.setContactTel(formatString(bo.getContactTel()));
        data.setContactRelation(formatString(bo.getContactRelation()));
        data.setEntryTime(formatString(bo.getEntryTime()));
        data.setRegistered(formatString(bo.getRegistered()));

        Employee tmp = employeeService.get(bo.getId());
        if (null == tmp) {
            throw new ApplicationException(ErrorEnum.IdNotExist.getCode(), ErrorEnum.IdNotExist.getMsg());
        }

        ResponseData<String> result = new ResponseData<>();
        try {
            employeeService.update(data, bo.getStudyExp(), bo.getWorkExp(), bo.getUpload());
            result.setData(String.valueOf(data.getId())).ok();
        } catch (Exception e) {
            logger.error("EmployeeController.update", e);
            result.responseCode(ErrorEnum.SystemError.getCode(), ErrorEnum.SystemError.getMsg());
        }
        return result;
    }

    @Override
    public ResponseData<String> updateStatus(@RequestBody Employee bo) {
        // 登陆校验
        if(!InterviewUtils.isLogin()){
            throw new ApplicationException(ErrorEnum.UserNotLogin.getCode(), ErrorEnum.UserNotLogin.getMsg());
        }
        // 参数校验
        checkIdLegal(bo.getId());
        Employee tmp = employeeService.get(bo.getId());
        if (null == tmp) {
            throw new ApplicationException(ErrorEnum.IdNotExist.getCode(), ErrorEnum.IdNotExist.getMsg());
        }
        Employee data = new Employee();
        data.setId(bo.getId());
        data.setStatus(bo.getStatus());
        // update
        ResponseData<String> result = new ResponseData<>();
        try {
            employeeService.updateSelective(data);
            result.setData(String.valueOf(data.getId())).ok();
        } catch (Exception e) {
            logger.error("EmployeeController.updateStatus", e);
            result.responseCode(ErrorEnum.SystemError.getCode(), ErrorEnum.SystemError.getMsg());
        }
        return result;
    }

    @Override
    @PropertyFiltration(clazz = Employee.class, includes = {"*"})
    public ResponseData<Employee> get(@PathVariable Long id) {
        checkIdLegal(id);
        Employee data = employeeService.get(id);
        // 10:待面试;20:未到达;30:面试通过;40:面试未通过;50:待定;60:入职中;70:入职完成(入职成功后，二维码不可用)
        if (null == data || null == data.getStatus() || data.getStatus() == StatusEnum.WTG.getCode() || data.getStatus() == StatusEnum.RZWC.getCode()) {
            throw new ApplicationException(ErrorEnum.IdNotExist.getCode(), ErrorEnum.IdNotExist.getMsg());
        } else {
            ResponseData<Employee> result = new ResponseData<>();
            try {
                EmployeeStudyExp studyExp = new EmployeeStudyExp();
                studyExp.setEnabledFlag(1L);
                studyExp.setEmployeeid(id);
                data.setStudyExpList(employeeStudyExpService.selectAll(studyExp));
                EmployeeWorkExp workExp = new EmployeeWorkExp();
                workExp.setEnabledFlag(1L);
                workExp.setEmployeeid(id);
                data.setWorkExpList(employeeWorkExpService.selectAll(workExp));
                EmployeeUpload upload = new EmployeeUpload();
                upload.setEnabledFlag(1L);
                upload.setEmployeeid(id);
                List<EmployeeUpload> uploadList = employeeUploadService.selectAll(upload);
                if (!CollectionUtils.isEmpty(uploadList)) {
                    for (EmployeeUpload tmp : uploadList) {
                        if (UploadTypeNameEnum.QRcode.getCode().equals(tmp.getTypeName())) {
                            uploadList.remove(tmp);
                            break;
                        }
                    }
                }
                data.setUploadList(uploadList);
                result.setData(data).ok();
            } catch (Exception e) {
                logger.error("EmployeeController.get", e);
                result.responseCode(ErrorEnum.SystemError.getCode(), ErrorEnum.SystemError.getMsg());
            }
            return result;
        }
    }

    @Override
    @PropertyFiltration(clazz = Employee.class, includes = {"*"})
    public ResponseData<StatisticsBo> statistics() {
        // 登陆校验
        if(!InterviewUtils.isLogin()){
            throw new ApplicationException(ErrorEnum.UserNotLogin.getCode(), ErrorEnum.UserNotLogin.getMsg());
        }
        StatisticsBo statisticsBo = new StatisticsBo();
        List<DepartmentCount> statistics = employeeService.statistics();
        Integer count = 0;
        for (DepartmentCount tmp : statistics){
            count += tmp.getCountNum();
        }
        statisticsBo.setInterviewCount(count);
        statisticsBo.setInterviewDepartmentList(statistics);
        statisticsBo.setInterviewTableList(employeeService.statisticsInterviewList());
        ResponseData<StatisticsBo> result = new ResponseData<>();
        result.setData(statisticsBo).ok();
        return result;
    }

    private String formatString(String str) {
        return StringUtils.isRealEmpty(str) ? null : str.trim();
    }

    private void checkNameLegal(String name) {
        if (StringUtils.isRealEmpty(name)) {
            throw new ApplicationException(ErrorEnum.NameNull.getCode(), ErrorEnum.NameNull.getMsg());
        }
    }

    private void checkTelLegal(String tel) {
        if (StringUtils.isRealEmpty(tel)) {
            throw new ApplicationException(ErrorEnum.TelNull.getCode(), ErrorEnum.TelNull.getMsg());
        }
        if (!checkTelphoneLegal(tel) && !checkFixphoneLegal(tel)) {
            throw new ApplicationException(ErrorEnum.TelLegal.getCode(), ErrorEnum.TelLegal.getMsg());
        }

    }

    /**
     * 正则验证
     * @param value 验证值
     * @param regex 正则表达式
     * @return true： 合法；false: 非法
     */
    private boolean patternMatcherLegal(String value, String... regex) {
        if (StringUtils.isRealEmpty(value)) {
            return false;
        }
        if (null == regex || regex.length == 0) {
            return false;
        }
        for (String tmp : regex) {
            if (Pattern.compile(tmp).matcher(value).find()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 验证手机号码   <br/>
     * 移动号码段:139、138、137、136、135、134、150、151、152、157、158、159、182、183、187、188、147    <br/>
     * 联通号码段:130、131、132、136、185、186、145    <br/>
     * 电信号码段:133、153、180、189    <br/>
     * @param telphone
     * @return
     */
    private boolean checkTelphoneLegal(String telphone) {
        return patternMatcherLegal(telphone.replaceAll(" ", "").replaceAll("-",""),
                "^((\\+86)|(86))?((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$");
    }

    // 固定电话
    private boolean checkFixphoneLegal(String fixphone) {
        return patternMatcherLegal(fixphone.replaceAll(" ", "").replaceAll("-",""),
                "^(0\\d{2}\\d{8}(\\d{1,4})?)|(0\\d{3}\\d{7,8}(\\d{1,4})?)$");
    }

    private void checkInterviewTimeLegal(Timestamp interviewTime) {
        if (null == interviewTime) {
            throw new ApplicationException(ErrorEnum.InterviewTimeNull.getCode(), ErrorEnum.InterviewTimeNull.getMsg());
        }
        if (interviewTime.getTime() <= DateUtils.getTimestamp().getTime()) {
            throw new ApplicationException(ErrorEnum.InterviewTimeBeforeCurrent.getCode(), ErrorEnum.InterviewTimeBeforeCurrent.getMsg());
        }
    }

    private void checkOfficeLocationLegal(String officeLocation) {
        if (StringUtils.isRealEmpty(officeLocation)) {
            throw new ApplicationException(ErrorEnum.OfficeLocationNull.getCode(), ErrorEnum.OfficeLocationNull.getMsg());
        }
    }

    private void checkEmailLegal(String email) {
        if (StringUtils.isRealEmpty(email)) {
            throw new ApplicationException(ErrorEnum.EmailNull.getCode(), ErrorEnum.EmailNull.getMsg());
        }
        if (!patternMatcherLegal(email.trim(), "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*")) {
            throw new ApplicationException(ErrorEnum.EmailLegal.getCode(), ErrorEnum.EmailLegal.getMsg());
        }
    }

    private void checkDepartmentLegal(String department) {
        if (StringUtils.isRealEmpty(department)) {
            throw new ApplicationException(ErrorEnum.DepartmentNull.getCode(), ErrorEnum.DepartmentNull.getMsg());
        }
        boolean isLegal = false;
        for (DepartmentEnum tmp : DepartmentEnum.values()) {
            if (tmp.getCode().equals(department.trim())) {
                isLegal = true;
                break;
            }
        }
        if (!isLegal) {
            throw new ApplicationException(ErrorEnum.DepartmentNotExist.getCode(), ErrorEnum.DepartmentNotExist.getMsg());
        }
    }

    private void checkEntryTimeLegal(Timestamp entryTime) {
        if (null != entryTime && entryTime.getTime() <= DateUtils.getTimestamp().getTime()) {
            throw new ApplicationException(ErrorEnum.EntryTimeBeforeCurrent.getCode(), ErrorEnum.EntryTimeBeforeCurrent.getMsg());
        }
    }

    private void checkIdLegal(Long id) {
        if (null == id) {
            throw new ApplicationException(ErrorEnum.IdNull.getCode(), ErrorEnum.IdNull.getMsg());
        }
    }

    private void checkPositionLegal(String position) {
        if (StringUtils.isRealEmpty(position)) {
            throw new ApplicationException(ErrorEnum.PositionNull.getCode(), ErrorEnum.PositionNull.getMsg());
        }
    }

}